//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "uEtat.h"
#include "uFncGDI.h"
#include "uSelPrinter.h"
#include "Printers.hpp"
//------------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CEdit"
#pragma link "CEditNum"
#pragma link "CGBox"
#pragma link "CBitBtn"
#pragma resource "*.dfm"

#define MODULE_TAG MODULE_TAG_SEL_PRINTER
TSelPrinter *SelPrinter;
#define RootKeyEtat     "\SoftWare\\eic\\etat"
#define Zoom            "Zoom"
#define PortraitPaysage "PortraitPaysage"

//------------------------------------------------------------------------------
__fastcall TSelPrinter::TSelPrinter(TComponent* Owner)
    : TForm(Owner)
{
  try{
    HANDLE   hPrinter;
    btnGED->Visible = GED_gGestionEnvoi;
    btnGED->Enabled = GED_gGestionEnvoi && GED_IsInstallee();

    m_Reg = new TRegistry();
    m_Reg->RootKey = HKEY_CURRENT_USER;
   // m_Reg->OpenKey( RootKeyEtat, true);

    int nDefautPrinter =  Printer()->PrinterIndex;
    for( int i = 0;
         i < Printer()->Printers->Count;
         i++)
    {
        Printer()->PrinterIndex = i;
        Printer()->GetPrinter( m_ADevice, m_ADriver, m_APort, (UINT)m_hDeviceMode);
        cbPrinter->Items->AddObject( m_ADevice, (TObject*)i);
    }
    Printer()->PrinterIndex = nDefautPrinter;
    cbPrinter->ItemIndex = cbPrinter->Items->IndexOfObject( (TObject*)nDefautPrinter);

    m_FOptions.Clear();
    m_hDeviceMode = NULL;
    m_pDevMode = NULL;
    memset( m_ADevice, 0, sizeof( m_ADevice));
    memset( m_ADriver, 0, sizeof( m_ADriver));
    memset( m_APort, 0, sizeof( m_APort));
  }CATCH_EXCEPTION( TAGL);

    cbPrinterChange(NULL);
}
__fastcall TSelPrinter::~TSelPrinter()
{
  delete m_Reg; m_Reg = NULL;
}
//------------------------------------------------------------------------------
void __fastcall TSelPrinter::FreeDevMode(int freeAll)
{
   try{
        if( m_hDeviceMode)
            ::_GlobalUnlock( TAGL, m_hDeviceMode);
        if(freeAll && m_hDeviceMode)
            ::_GlobalFree( TAGL, m_hDeviceMode);
        m_pDevMode = NULL;
        m_hDeviceMode = NULL;
        memset( m_ADevice, 0, sizeof( m_ADevice));
        memset( m_ADriver, 0, sizeof( m_ADriver));
        memset( m_APort, 0, sizeof( m_APort));
    }CATCH_EXCEPTION( TAGL);
}
//------------------------------------------------------------------------------
int __fastcall TSelPrinter::ShowModal(void)
{
    int Retour;

    rbPageCourante->Enabled = m_FOptions.Contains( poSelection);
    rbPages->Enabled = m_FOptions.Contains( poPageNums) && (enDe->Min < enA->Max);
    lblDeLaPage->Enabled = rbPages->Enabled;
    lblaLaPage->Enabled = rbPages->Enabled;
    Refresh();

    Retour = inherited::ShowModal();
    return Retour;
}
//------------------------------------------------------------------------------
void        __fastcall TSelPrinter::Refresh()
{
  try{
    inherited::Refresh();
    switch( PrintRange)
    {
        case prAllPages  : enDe->Enabled = false; enA->Enabled = false; break;
        case prSelection : enDe->Enabled = false; enA->Enabled = false; break;
        case prPageNums  : enDe->Enabled = true;  enA->Enabled = true;  break;
    }
    bool AssemblagePossible = (enCopies->Valeur > 1) && (PrintRange != prSelection),
         AssemblageSupporte = m_pDevMode && (m_pDevMode->dmFields & DM_COLLATE );
    cbAssemblee->Visible = AssemblagePossible;
    cbAssemblee->Enabled = AssemblageSupporte && AssemblagePossible;
    lblAssembleeUnsupported->Visible = AssemblagePossible && !AssemblageSupporte;
    if( !AssemblageSupporte) cbAssemblee->Checked = false;
    ImNonAssemblees->Visible = AssemblageSupporte && AssemblagePossible && !cbAssemblee->Checked;
    ImAssemblees->Visible = AssemblageSupporte && AssemblagePossible && cbAssemblee->Checked;
  }CATCH_EXCEPTION( TAGL);
}
//------------------------------------------------------------------------------
void __fastcall TSelPrinter::cbPrinterChange(TObject *Sender)
{
    Printer()->PrinterIndex = (int)cbPrinter->Items->Objects[cbPrinter->ItemIndex];

    Init();
    Refresh();
}
//------------------------------------------------------------------------------
/*#define Aff( t, t2)  ( (pDevMode->dmFields & t)? (AnsiString(#t) +"\t"+ AnsiString(pDevMode->t2)+"\n") : ((pDevMode->t2=0)?EmptyStr:EmptyStr))
#define Aff2( t, t2)  ( (pDevMode->dmFields & t)? (AnsiString(#t) +"\t"+ AnsiString((char*)pDevMode->t2)+"\n") : (((*pDevMode->t2)=0)?EmptyStr:EmptyStr))
void __fastcall showDevMode( const AnsiString &s, DEVMODE *pDevMode)
{
ShowMessage( s+
AnsiString( (char*)pDevMode->dmDeviceName)+
Aff( DM_ORIENTATION, dmOrientation)+
Aff( DM_PAPERSIZE, dmPaperSize)+
Aff( DM_PAPERLENGTH, dmPaperLength)+
Aff( DM_PAPERWIDTH, dmPaperWidth)+
Aff( DM_SCALE, dmScale)+
Aff( DM_COPIES, dmCopies)+
Aff( DM_DEFAULTSOURCE, dmDefaultSource)+
Aff( DM_PRINTQUALITY, dmPrintQuality)+
//Aff( DM_POSITION, dmPosition)+
//Aff( DM_DISPLAYORIENTATION dmDisplayOrientation
//Aff( DM_DISPLAYFIXEDOUTPUT dmDisplayFixedOutput
Aff( DM_COLOR, dmColor)+
Aff( DM_DUPLEX, dmDuplex)+
Aff( DM_YRESOLUTION, dmYResolution)+
Aff( DM_TTOPTION, dmTTOption)+
Aff( DM_COLLATE, dmCollate)+
Aff2( DM_FORMNAME, dmFormName)+
Aff( DM_LOGPIXELS, dmLogPixels)+
Aff( DM_BITSPERPEL, dmBitsPerPel)+
Aff( DM_PELSWIDTH, dmPelsWidth)+
Aff( DM_PELSHEIGHT, dmPelsHeight)+
Aff( DM_DISPLAYFLAGS, dmDisplayFlags)+
Aff( DM_NUP, dmNup)+
Aff( DM_DISPLAYFREQUENCY, dmDisplayFrequency)+
Aff( DM_ICMMETHOD, dmICMMethod)+
Aff( DM_ICMINTENT, dmICMIntent)+
Aff( DM_MEDIATYPE, dmMediaType)+
Aff( DM_DITHERTYPE, dmDitherType)+
Aff( DM_PANNINGWIDTH, dmPanningWidth)+
Aff( DM_PANNINGHEIGHT, dmPanningHeight)
);
}                                          */
void __fastcall TSelPrinter::btProprieteClick(TObject *Sender)
{
    HANDLE      hPrinter;

   /* Start by opening the printer */
    if( m_pDevMode && (cbPrinter->ItemIndex != -1) &&
        ::OpenPrinter(cbPrinter->Items->Strings[cbPrinter->ItemIndex].c_str(), &hPrinter, NULL) )
    {
         AnsiString CurrentDir = GetCurrentDir();
//        InitDevMode( );
        if( (m_pDevMode->dmFields & DM_COPIES) && enCopies->Visible)
            m_pDevMode->dmCopies = enCopies->Valeur;
        if( (m_pDevMode->dmFields & DM_COLLATE) && cbAssemblee->Visible && cbAssemblee->Enabled)
            m_pDevMode->dmCollate = cbAssemblee->Checked;

        LONG lRet = ::_DocumentProperties(TAGL, Handle, hPrinter, cbPrinter->Items->Strings[cbPrinter->ItemIndex].c_str(), m_pDevMode, m_pDevMode, DM_IN_BUFFER | DM_IN_PROMPT| DM_OUT_BUFFER);

        SetCurrentDir( CurrentDir);
        if( lRet == IDOK)
        {
            if( (m_pDevMode->dmFields & DM_COPIES) && enCopies->Visible)
                enCopies->Valeur = m_pDevMode->dmCopies;
            if( (m_pDevMode->dmFields & DM_COLLATE) && cbAssemblee->Visible && cbAssemblee->Enabled)
                cbAssemblee->Checked = m_pDevMode->dmCollate;
        }else
        {
            if( (m_pDevMode->dmFields & DM_COPIES) && enCopies->Visible)
                m_pDevMode->dmCopies = enCopies->Valeur;
            if( (m_pDevMode->dmFields & DM_COLLATE) && cbAssemblee->Visible && cbAssemblee->Enabled)
                m_pDevMode->dmCollate = cbAssemblee->Checked;
        }

        ::_ClosePrinter(TAGL, hPrinter);
    }
}
//------------------------------------------------------------------------------
void __fastcall TSelPrinter::Init()
{
    HANDLE      hPrinter;
  try{
    btnOK->Enabled = false;
    btPropriete->Enabled = false;
    lblEtat->Caption = "Ouverture de l'imprimante";
    lblType->Caption = EmptyStr;
    lblEmplacement->Caption = EmptyStr;
    lblCommentaire->Caption = EmptyStr;
    Refresh();
    if( (cbPrinter->ItemIndex != -1) &&
        ::OpenPrinter(cbPrinter->Items->Strings[cbPrinter->ItemIndex].c_str(), &hPrinter, NULL))
    {
        PRINTER_INFO_2 *printerInfo;
        DWORD dw=0;
        if( !::GetPrinter( hPrinter, 2, NULL, 0, &dw) && GetLastError( ) == 122)
        {
            printerInfo = (PRINTER_INFO_2 *)::_GlobalAlloc( TAGL, GPTR, dw);
            ChkSDK( TAGL, ::GetPrinter( hPrinter, 2, (LPBYTE)printerInfo, dw, &dw), 0);
            switch( printerInfo->Status)
            {
                case PRINTER_STATUS_BUSY              : lblEtat->Caption = "Occupé ;"; break;
                case PRINTER_STATUS_DOOR_OPEN         : lblEtat->Caption = "Porte ouverte ;"; break;
                case PRINTER_STATUS_ERROR             : lblEtat->Caption = "Erreur ;"; break;
                case PRINTER_STATUS_INITIALIZING      : lblEtat->Caption = "Initialisation ;"; break;
                case PRINTER_STATUS_IO_ACTIVE         : lblEtat->Caption = "E/S active ;"; break;
                case PRINTER_STATUS_MANUAL_FEED       : lblEtat->Caption = "Alimentation manuelle ;"; break;
                case PRINTER_STATUS_NO_TONER          : lblEtat->Caption = "Toner absent ;"; break;
                case PRINTER_STATUS_NOT_AVAILABLE     : lblEtat->Caption = "Non disponible ;"; break;
                case PRINTER_STATUS_OFFLINE           : lblEtat->Caption = "L'imprimante est éteinte."; break;
                case PRINTER_STATUS_OUT_OF_MEMORY     : lblEtat->Caption = "Mémoire insuffisante ;"; break;
                case PRINTER_STATUS_OUTPUT_BIN_FULL   : lblEtat->Caption = "Bac de sortie plein ;"; break;
                case PRINTER_STATUS_PAGE_PUNT         : lblEtat->Caption = "Page non imprimable ;"; break;
                case PRINTER_STATUS_PAPER_JAM         : lblEtat->Caption = "Bourrage papier ;"; break;
                case PRINTER_STATUS_PAPER_OUT         : lblEtat->Caption = "Papier épuisé ;"; break;
                case PRINTER_STATUS_PAPER_PROBLEM     : lblEtat->Caption = "Problème de papier ;"; break;
                case PRINTER_STATUS_PAUSED            : lblEtat->Caption = "En pause ;"; break;
                case PRINTER_STATUS_PENDING_DELETION  : lblEtat->Caption = "En attente de suppression ;"; break;
                case PRINTER_STATUS_POWER_SAVE        : lblEtat->Caption = "Mode d'économie d'énergie ;"; break;
                case PRINTER_STATUS_PRINTING          : lblEtat->Caption = "Impression ;"; break;
                case PRINTER_STATUS_PROCESSING        : lblEtat->Caption = "Traitement ;"; break;
                case PRINTER_STATUS_SERVER_UNKNOWN    : lblEtat->Caption = "Inconnu ;"; break;
                case PRINTER_STATUS_TONER_LOW         : lblEtat->Caption = "Cartouche d'encre presque vide ;"; break;
                case PRINTER_STATUS_USER_INTERVENTION : lblEtat->Caption = "Intervention utilisateur ;"; break;
                case PRINTER_STATUS_WAITING           : lblEtat->Caption = "Attente ;"; break;
                case PRINTER_STATUS_WARMING_UP        : lblEtat->Caption = "Préchauffage ;"; break;
                default                               : lblEtat->Caption = "Prêt ;"; break;
            }
            lblType->Caption = printerInfo->pDriverName;
            lblEmplacement->Caption = (printerInfo->pLocation && printerInfo->pLocation[0])?printerInfo->pLocation:printerInfo->pPortName;;
            lblCommentaire->Caption = printerInfo->pComment;

            FreeDevMode();
            Printer()->GetPrinter( m_ADevice, m_ADriver, m_APort, (UINT)m_hDeviceMode);
            if( printerInfo->pDevMode)
            {
                m_hDeviceMode = (HGLOBAL)::_GlobalAlloc( TAGL, GMEM_MOVEABLE, printerInfo->pDevMode->dmSize + printerInfo->pDevMode->dmDriverExtra);
                m_pDevMode = (DEVMODE*)::_GlobalLock( TAGL, m_hDeviceMode);
                memcpy( m_pDevMode, printerInfo->pDevMode, printerInfo->pDevMode->dmSize + printerInfo->pDevMode->dmDriverExtra);
                btPropriete->Enabled = true;
            }else
            {
                try{
                    DEVMODE StubDevMode; int nSize;
                    nSize = ::_DocumentProperties( TAGL, 0, hPrinter, cbPrinter->Items->Strings[cbPrinter->ItemIndex].c_str(),
                                                                   &StubDevMode, &StubDevMode, 0);
                    m_hDeviceMode = (HGLOBAL)::_GlobalAlloc(TAGL, GHND, nSize);
                    m_pDevMode = (DEVMODE*)::_GlobalLock( TAGL, m_hDeviceMode);
                    ::_DocumentProperties( TAGL, 0, hPrinter, cbPrinter->Items->Strings[cbPrinter->ItemIndex].c_str(),
                                                          m_pDevMode, m_pDevMode, DM_OUT_BUFFER);
                }catch( ...){
                    btPropriete->Enabled = false;
                    FreeDevMode();
                }
            }
    //

            ::_GlobalFree( TAGL, printerInfo);
            ::_ClosePrinter( TAGL, hPrinter);

            edZoom->Valeur = 100;
            cbPaysagePortraitAssembles->Checked = true;

            m_Reg->OpenKey( RootKeyEtat, true);
            if( m_Reg->ValueExists( cbPrinter->Items->Strings[cbPrinter->ItemIndex]))
            {
              edZoom->Valeur = m_Reg->ReadInteger( cbPrinter->Items->Strings[cbPrinter->ItemIndex]);
              m_Reg->DeleteValue( cbPrinter->Items->Strings[cbPrinter->ItemIndex]);
            }
            m_Reg->CloseKey();

            if( m_Reg->OpenKey( AnsiString(RootKeyEtat)+"\\"+cbPrinter->Items->Strings[cbPrinter->ItemIndex], false))
            {
              if( m_Reg->ValueExists( Zoom))            edZoom->Valeur = m_Reg->ReadInteger( Zoom);
              if( m_Reg->ValueExists( PortraitPaysage)) cbPaysagePortraitAssembles->Checked = m_Reg->ReadBool( PortraitPaysage);
              m_Reg->CloseKey();
            }
            cbPaysagePortraitAssembles->Visible = !cbPaysagePortraitAssembles->Checked;



            btnOK->Enabled = true;
        }else
        {
            ::_ClosePrinter(TAGL, hPrinter);
            goto pb;
        }
    }else{
        pb :
        lblEtat->Caption = "Problème de connexion";
        lblType->Caption = EmptyStr;
        lblEmplacement->Caption = EmptyStr;
        lblCommentaire->Caption = EmptyStr;
        FreeDevMode();
        btPropriete->Enabled = false;
        btnOK->Enabled = false;
    }

    }CATCH_EXCEPTION( TAGL);
}

void __fastcall TSelPrinter::rbToutClick(TObject *Sender)
{
    Refresh();
}
//------------------------------------------------------------------------------

void __fastcall TSelPrinter::enCopiesChange(TObject *Sender)
{
    Refresh();
    if( !enCopies->Tag)
    {
        enCopies->Tag = 1;
        udCopies->Position = enCopies->Valeur;
        enCopies->Tag = 0;
    }
}
void __fastcall TSelPrinter::udCopiesChangingEx(TObject *Sender,
      bool &AllowChange, short NewValue, TUpDownDirection Direction)
{
    AllowChange = false;
    if( !enCopies->Tag)
    {
        enCopies->Tag = 1;
        if( (NewValue >= enCopies->Min) && (NewValue <= enCopies->Max))
        {
            enCopies->Valeur = NewValue;
            AllowChange = true;
        }else
            AllowChange = false;
        enCopies->Tag = 0;
    }
}
//------------------------------------------------------------------------------

void __fastcall TSelPrinter::cbAssembleeClick(TObject *Sender)
{
    Refresh();
}
//------------------------------------------------------------------------------
TPrintRange __fastcall TSelPrinter::GetPrintRange( )
{
    return    rbTout->Checked        ?prAllPages
            : rbPageCourante->Checked?prSelection
            :                         prPageNums;
}
void        __fastcall TSelPrinter::SetPrintRange( TPrintRange p)
{
    switch( p)
    {
        case prAllPages  : rbTout->Checked         = true; break;
        case prSelection : rbPageCourante->Checked = true; break;
        case prPageNums  : rbPages->Checked        = true; break;
    }
}
//------------------------------------------------------------------------------
int         __fastcall TSelPrinter::GetFromPage( )
{
    return (int)(enDe->StateNS?enDe->Min:enDe->Valeur);
}
void        __fastcall TSelPrinter::SetFromPage( int i)
{
    enDe->Valeur = i;
}
//------------------------------------------------------------------------------
int         __fastcall TSelPrinter::GetToPage( )
{
    return (int)(enA->StateNS?enA->Max:enA->Valeur);
}
void        __fastcall TSelPrinter::SetToPage( int i)
{
    enA->Valeur = i;
}
//------------------------------------------------------------------------------
int         __fastcall TSelPrinter::GetMinPage( )
{
    return (int)enDe->Min;
}
void        __fastcall TSelPrinter::SetMinPage( int i)
{
    enDe->Min = i;
}
//------------------------------------------------------------------------------
int         __fastcall TSelPrinter::GetMaxPage( )
{
    return (int)enA->Max;
}
void        __fastcall TSelPrinter::SetMaxPage( int i)
{
    enA->Max = i;
}
//---------------------------------------------------------------------------
AnsiString  __fastcall TSelPrinter::GetDocName( )
{
    return rbPages->Caption;
}
void        __fastcall TSelPrinter::SetDocName( const AnsiString &s)
{
    rbPages->Caption = s;
}
//---------------------------------------------------------------------------
int         __fastcall TSelPrinter::GetCopies( )
{
    return enCopies->Valeur;
}
void        __fastcall TSelPrinter::SetCopies( int i)
{
    enCopies->Valeur = i;
}
//---------------------------------------------------------------------------
bool        __fastcall TSelPrinter::GetCollate( )
{
    return cbAssemblee->Checked;
}
void        __fastcall TSelPrinter::SetCollate( bool b)
{
    cbAssemblee->Checked = b;
}
//---------------------------------------------------------------------------
bool        __fastcall TSelPrinter::GetCopiesShow( )
{
    return gpbCopies->Visible;
}
void        __fastcall TSelPrinter::SetCopiesShow( bool b)
{
    gpbCopies->Visible = b;
}
//---------------------------------------------------------------------------

void __fastcall TSelPrinter::enDeChange(TObject *Sender)
{
    enA->Min  = enDe->Valeur;
}
//---------------------------------------------------------------------------

void __fastcall TSelPrinter::enAChange(TObject *Sender)
{
    enDe->Max  = enA->Valeur;
}

//---------------------------------------------------------------------------

void __fastcall TSelPrinter::btnOKClick(TObject *Sender)
{
    try{
        if( edZoom->Valeur == 100 && cbPaysagePortraitAssembles->Checked)
        {
          m_Reg->OpenKey( RootKeyEtat, true);
          if( m_Reg->KeyExists( cbPrinter->Items->Strings[cbPrinter->ItemIndex]))
            m_Reg->DeleteKey( cbPrinter->Items->Strings[cbPrinter->ItemIndex]);
          m_Reg->CloseKey();
        }else if( m_Reg->OpenKey( AnsiString(RootKeyEtat)+"\\"+cbPrinter->Items->Strings[cbPrinter->ItemIndex], true))
        {
          if( edZoom->Valeur != 100)                      m_Reg->WriteInteger( Zoom, edZoom->Valeur);
          else if( m_Reg->ValueExists( Zoom))             m_Reg->DeleteValue( Zoom);

          if( !cbPaysagePortraitAssembles->Checked)       m_Reg->WriteBool( PortraitPaysage, false);
          else if( m_Reg->ValueExists( PortraitPaysage))  m_Reg->DeleteValue( PortraitPaysage);
          m_Reg->CloseKey();
        }
        if( m_hDeviceMode)
            Printer()->SetPrinter( m_ADevice, m_ADriver, m_APort, (UINT)m_hDeviceMode);
        FreeDevMode(false);
    }CATCH_EXCEPTION( TAGL);
}
//---------------------------------------------------------------------------

void __fastcall TSelPrinter::btnCancelClick(TObject *Sender)
{
    FreeDevMode();
}
//---------------------------------------------------------------------------


void __fastcall TSelPrinter::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if( Key == VK_F12)
  {
      cbPaysagePortraitAssembles->Checked = !cbPaysagePortraitAssembles->Checked;
      if( !cbPaysagePortraitAssembles->Visible)
        cbPaysagePortraitAssembles->Visible = true;
  }

}
//---------------------------------------------------------------------------

void __fastcall TSelPrinter::btnGEDClick(TObject *Sender)
{
    try{
        /*if( edZoom->Valeur == 100 && cbPaysagePortraitAssembles->Checked)
        {
          m_Reg->OpenKey( RootKeyEtat, true);
          if( m_Reg->KeyExists( cbPrinter->Items->Strings[cbPrinter->ItemIndex]))
            m_Reg->DeleteKey( cbPrinter->Items->Strings[cbPrinter->ItemIndex]);
          m_Reg->CloseKey();
        }else if( m_Reg->OpenKey( AnsiString(RootKeyEtat)+"\\"+cbPrinter->Items->Strings[cbPrinter->ItemIndex], true))
        {
          if( edZoom->Valeur != 100)                      m_Reg->WriteInteger( Zoom, edZoom->Valeur);
          else if( m_Reg->ValueExists( Zoom))             m_Reg->DeleteValue( Zoom);

          if( !cbPaysagePortraitAssembles->Checked)       m_Reg->WriteBool( PortraitPaysage, false);
          else if( m_Reg->ValueExists( PortraitPaysage))  m_Reg->DeleteValue( PortraitPaysage);
          m_Reg->CloseKey();
        }*/
        if( m_hDeviceMode)
            Printer()->SetPrinter( m_ADevice, m_ADriver, m_APort, (UINT)m_hDeviceMode);
        FreeDevMode(false);
    }CATCH_EXCEPTION( TAGL);
}
//---------------------------------------------------------------------------

void __fastcall TSelPrinter::edZoomChange(TObject *Sender)
{
  UpDown1->Position = edZoom->Valeur;  
}
//---------------------------------------------------------------------------

